package com.chefu.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chefu.common.exception.CfException;
import com.chefu.common.exception.ExceptionEnum;
import com.chefu.common.utils.BeanHelper;
import com.chefu.system.mapper.DeptMapper;
import com.chefu.system.mapper.EmpMapper;
import com.chefu.system.mapper.RoleMapper;
import com.chefu.system.mapper.UserMapper;
import com.chefu.system.pojo.Dept;
import com.chefu.system.pojo.Emp;
import com.chefu.system.pojo.Role;
import com.chefu.system.pojo.User;
import com.chefu.system.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chefu.system.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import javax.jws.soap.SOAPBinding;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author goodgoodstudy
 * @since 2021-03-30
 */
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Override
    public List<UserVo> findByPage(Integer page, Integer pageSize, String username, String name, String phone) {
        //创建分页查询
        IPage iPage = new Page(page, pageSize);
        //创建查询条件，并添加查询条件
        QueryWrapper queryWrapper = Wrappers.query();

        if (username != null) {
            queryWrapper.like("user_name", username);
        }

        if (name != null) {
            queryWrapper.like("ar_name", name);
        }

        if (phone != null) {
            queryWrapper.eq("phone", phone);
        }
        //执行查询，并处理结果
        iPage = userMapper.selectPage(iPage, queryWrapper);
        //创建集合，接收数据
        List<UserVo> userVoList = new ArrayList<>();
        List<User> userList = iPage.getRecords();
        //创建一个VO，用来返回给前端的数据
        UserVo userVo = null;
        //封装数据
        for (User user : userList) {
            userVo = BeanHelper.copyProperties(user, UserVo.class);
            //根据员工id查询员工
            Emp emp = empMapper.selectById(user.getEmpId());
            //根据部门id查询部门
            Dept dept = deptMapper.selectById(emp.getDeptId());

            userVo.setDeptName(dept.getArName());
            //根据userId查询所有角色
            List<Role> roleList = roleMapper.findUserRoleByUserId(user.getUserId());
            QueryWrapper wrapper = Wrappers.query();
            //遍历角色数据，封装数据
            for (Role role : roleList) {
                userVo.setRoleName(role.getRoleName());
            }

            //把封装好的数据，添加到集合中
            userVoList.add(userVo);
        }
        //返回数据
        return userVoList;
    }

    @Override
    public List<Emp> findAll() {
        List<Emp> empList = empMapper.selectList(null);
        List<Emp> emps = new ArrayList<>();
        for (Emp emp : empList) {
            if (emp.getEmployeeStatus() == 0) {
                emps.add(emp);
            }
        }
        return emps;
    }

    @Override
    public List<Role> findAllRole() {
        return roleMapper.selectList(null);
    }

    @Override
    public void create(Long roleId, User user) {
        try {
            String password = passwordEncoder.encode(user.getPassword());
            user.setPassword(password);
            Emp emp = empMapper.selectById(user.getEmpId());
            user.setArName(emp.getEmployeeName());
            user.setPhone(emp.getEmployeePhone());
            user.setEmail(emp.getEmployeeEmail());
            userMapper.insert(user);

            userMapper.insertUserRole(roleId, user.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
            throw new CfException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    @Override
    public User findById(Long id) {
        User u = new User();
        User user = userMapper.selectById(id);
        u.setUserId(user.getUserId());
        u.setArName(user.getArName());
        u.setUserName(user.getUserName());

        return u;
    }

    @Override
    public void updateByUser(Long roleId, User user) {
        String password = passwordEncoder.encode(user.getPassword());
        user.setPassword(password);
        try {
            userMapper.updateById(user);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CfException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

        try {
            userMapper.deleteUserRoleByUserId(user.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
            throw new CfException(ExceptionEnum.DELETE_OPERATION_FAIL);
        }
        try {
            userMapper.insertUserRole(roleId, user.getUserId());
        } catch (Exception e) {
            e.printStackTrace();
            throw new CfException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    @Override
    public void lock(Long userId, Integer status) {
        User user = userMapper.selectById(userId);
        user.setStatus(status);
        try {
            userMapper.updateById(user);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CfException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }

    @Override
    public User findUserByNameAndPwd(String username, String password) {
        User user = new User();

        user.setUserName(username);

        QueryWrapper queryWrapper = Wrappers.query(user);

        User loginUser = userMapper.selectOne(queryWrapper);
        if (loginUser == null) {
            throw new CfException(ExceptionEnum.INVALID_USERNAME_PASSWORD);
        }


        return loginUser;
    }
}
